package com.hl.util.KL.SocketClients;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.Handler;
import android.os.Message;

class SocketCallback implements DisconnectCallback, ErrorCallback,
		EventCallback, JSONCallback {
	ISocketInter inter;
	SocketClient client;
	boolean reciveOnMain = false;

	private static Handler mainHandler = new Handler() {
		public void handleMessage(Message msg) {
			// msg.what
			// 1 connected
			// 2 disconnected
			// 3 on
			// 4 error
			// 5 forceOffline
			// 6 connecting
			// 7 reconnected
			// 8 reconnecting
			toMainData mainData = (toMainData) msg.obj;
			if (mainData.inter == null) {
				return;
			}
			try {

				switch (msg.what) {
				case 1:
					mainData.inter.connected();
					break;
				case 2:
					mainData.inter.disconnected();
					break;
				case 3:
					ReciveMessage(mainData.inter, mainData.message,
							(JSONObject) mainData.obj1);
					break;
				case 4:
					mainData.inter.onError((SocketException) mainData.obj1);
					break;
				case 5:
					try {
						mainData.inter.forceOffline((JSONObject) mainData.obj1);
					} catch (Exception e) {
						e.printStackTrace();
					} finally {
						mainData.client.disconnect();
					}
					break;
				case 6:
					mainData.inter.connecting();
					break;
				case 7:
					mainData.inter.reconnected();
					break;
				case 8:
					mainData.inter.reconnecting();
					break;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		};
	};

	public static void ReciveMessage(ISocketInter inter, String methodName,
			JSONObject args) {
		try {
			Method reciveMethod = inter.getClass().getMethod(methodName,
					JSONObject.class);
			if (reciveMethod != null) {
				reciveMethod.invoke(inter, args);
			}
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onJSON(JSONObject json, Acknowledge acknowledge) {

	}

	@Override
	public void onEvent(String event, JSONArray argument,
			Acknowledge acknowledge) {
		Message msg = new Message();
		toMainData mainData = new toMainData();
		mainData.inter = inter;
		try {
			if (event.equalsIgnoreCase("message")) {
				msg.what = 3;
				mainData.message = ((JSONObject) argument.get(0))
						.getString("eventType");
				mainData.obj1 = ((JSONObject) argument.get(0)).get("data");
			} else if (event.equalsIgnoreCase("forceOffline")) {
				msg.what = 5;
				client.isForceOffline = true;
				mainData.message = event;
				mainData.obj1 = argument.get(0);
			} else {
				return;
			}
		} catch (JSONException e) {
			e.printStackTrace();
			return;
		}
		if (reciveOnMain) {
			mainData.client = client;
			msg.obj = mainData;
			mainHandler.sendMessage(msg);
		} else {
			try {
				if (msg.what == 3) {
					ReciveMessage(mainData.inter, mainData.message,
							(JSONObject) mainData.obj1);
				} else if (msg.what == 5) {
					try {
						inter.forceOffline((JSONObject) mainData.obj1);
					} catch (Exception e) {
					} finally {
						client.disconnect();
					}

				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void onError(ErrorCode code, String error) {
		SocketException ex = new SocketException(error, code);
		if (client.getConnectStatus() == ConnectStatus.Disconnected
				&& code == ErrorCode.HandshakeFailed
				&& client.isAutoReconnect() && inter.isReconnect()) {
			client.delayReconnect();
		}
		if (reciveOnMain) {
			Message msg = new Message();
			msg.what = 4;
			toMainData mainData = new toMainData();
			mainData.inter = inter;
			mainData.message = "onError";
			mainData.obj1 = ex;

			msg.obj = mainData;
			mainHandler.sendMessage(msg);
		} else {
			inter.onError(ex);
		}
	}

	@Override
	public void onDisconnect(Exception e) {
		client.setConnectStatus(ConnectStatus.Disconnected);
		if (!client.isForceOffline && client.isAutoReconnect()
				&& inter.isReconnect()) {
			client.delayReconnect();
		}
		if (reciveOnMain) {
			Message msg = new Message();
			msg.what = 2;
			toMainData mainData = new toMainData();
			mainData.inter = inter;
			mainData.message = "disconnected";
			msg.obj = mainData;
			mainHandler.sendMessage(msg);
		} else {
			inter.disconnected();
		}
	}

	public void onConnect(Exception ex, SocketIOClient client) {
		if (reciveOnMain) {
			Message msg = new Message();
			msg.what = 1;
			toMainData mainData = new toMainData();
			mainData.inter = inter;
			mainData.message = "connected";
			msg.obj = mainData;
			mainHandler.sendMessage(msg);
		} else {
			inter.connected();
		}
	}

	public void onConnecting() {
		if (reciveOnMain) {
			Message msg = new Message();
			msg.what = 6;
			toMainData mainData = new toMainData();
			mainData.inter = inter;
			mainData.message = "connecting";
			msg.obj = mainData;
			mainHandler.sendMessage(msg);
		} else {
			inter.connecting();
		}
	}

	public void onReconnecting() {
		if (reciveOnMain) {
			Message msg = new Message();
			msg.what = 8;
			toMainData mainData = new toMainData();
			mainData.inter = inter;
			mainData.message = "reconnecting";
			msg.obj = mainData;
			mainHandler.sendMessage(msg);
		} else {
			inter.reconnecting();
		}
	}

	public void onReconnected() {
		if (reciveOnMain) {
			Message msg = new Message();
			msg.what = 7;
			toMainData mainData = new toMainData();
			mainData.inter = inter;
			mainData.message = "reconnected";
			msg.obj = mainData;
			mainHandler.sendMessage(msg);
		} else {
			inter.reconnected();
		}
	}
}
